﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.IO;
using WeifenLuo.WinFormsUI.Docking;

namespace VoltGameEditor
{
	public class AppSettings
	{
		public class General
		{
			public static bool FirstRun = false;
			public static bool AutoUpdate = true;
			public static int UndoRedoBuffer = 64; //MB
			public static int GridSize = 16;
			public static Globals.Game GameMode = Globals.Game.Quake_2;
			public static string[] RecentFiles = new string[]{};
		}
		public class Rendering
		{
			public static Globals.Renderers Renderer = Globals.Renderers.TaoOpenGL;
			public static Globals.Filtering Filtering = Globals.Filtering.Bilinear;
			public static bool EnableLighting = true;
			public static bool EnableTransparency = true;
			public static bool WireframeInGame = false;
			public static bool ModelsIn3dView = true;
			public static bool DoubleBuffering = true;
			public static string LightingWhileMoving = "Simple";
			public static string LightingWhileNotMoving = "Full";
			public static int BufferDepth = 16;

		}
		public class Fog
		{
			public static bool EnableFog = true;
			public static int FogDensity = 50;
			public static int FogDistance = 1024;
		}
		public class MouseKeyboardSettings
		{
			public static Dictionary<Globals.Bind, Keys> BoundKeys = new Dictionary<Globals.Bind, Keys>();
			public static void AssignKeys2Dict() //Default Key Values
			{
				BoundKeys[Globals.Bind.ToggleConsole] = Keys.F1;
				BoundKeys[Globals.Bind.Help] = Keys.Oemtilde;
				BoundKeys[Globals.Bind.Grid_Up] = Keys.Add;
				BoundKeys[Globals.Bind.Grid_Down] = Keys.Subtract;

				BoundKeys[Globals.Bind.Cam_Pivot] = Keys.O;
				BoundKeys[Globals.Bind.Cam_Zoom] = Keys.P;
				BoundKeys[Globals.Bind.Move_Forward] = Keys.W;
				BoundKeys[Globals.Bind.Move_Back] = Keys.S;
				BoundKeys[Globals.Bind.Turn_Left] = Keys.A;
				BoundKeys[Globals.Bind.Turn_Right] = Keys.D;
				BoundKeys[Globals.Bind.View_Up] = Keys.Q;
				BoundKeys[Globals.Bind.View_Down] = Keys.E;
				BoundKeys[Globals.Bind.Run] = Keys.ShiftKey;
			}

			public static void SetKeyDefaults()
			{
				AssignKeys2Dict();
				//set the button texts to the default values...
				Program.Settings.button1.Text = BoundKeys[Globals.Bind.Cam_Pivot].ToString().ToLower();
				Program.Settings.button2.Text = BoundKeys[Globals.Bind.Cam_Zoom].ToString().ToLower();
				Program.Settings.button3.Text = BoundKeys[Globals.Bind.Move_Forward].ToString().ToLower();
				Program.Settings.button4.Text = BoundKeys[Globals.Bind.Move_Back].ToString().ToLower();
				Program.Settings.button5.Text = BoundKeys[Globals.Bind.Turn_Right].ToString().ToLower();
				Program.Settings.button6.Text = BoundKeys[Globals.Bind.Turn_Left].ToString().ToLower();
				Program.Settings.button7.Text = BoundKeys[Globals.Bind.View_Up].ToString().ToLower();
				Program.Settings.button8.Text = BoundKeys[Globals.Bind.View_Down].ToString().ToLower();
				Program.Settings.button9.Text = BoundKeys[Globals.Bind.Run].ToString().ToLower();
			}
		}
		public class MapView
		{
			public static bool SelectedObjectRulers = true;
			public static bool HighlightObectsOnHover = true;
			public static bool BrushSubtractionOnlyWithCutter = true;
			public static Dictionary<string, DockState> DockedWindowPositions = new Dictionary<string, DockState>();
		}
		public class Theming
		{
			public static string Theme = "Default";
			public static Color Color_Grid = new Color();
			public static Color Color_2dViewBG = new Color();
			public static Color Color_3dViewBG = new Color();
			public static Color Color_BrushEnts = new Color();
			public static Color Color_Dups = new Color();
			public static Color Color_ObjectLines = new Color();
			public static Color Color_VertexHandles = new Color();
			public static Color Color_SelectedObjects = new Color();
			public static Color Color_Fog = new Color();
		}

		public class Gamemode
		{
			public static string[] Games = new string[] { "Quake 1", "Quake 2", "Quake III Arena" };
			public static string GameExecutable = "C:\\";
			public static string GameTexDir = "C:\\";
			public static List<string> BuildTools = new List<string>();
			public static IDictionary CustomBuildMenu = new Dictionary<string, List<string>>();
			public static bool buildOutputInConsole = true;
		}

		public static void LoadSettings()
		{
			Program.Settings.AutoUpdate.Checked = AppSettings.General.AutoUpdate;
			Program.Settings.numericUpDown2.Value = AppSettings.General.UndoRedoBuffer;

			Program.Settings.cb_fog.Checked = AppSettings.Fog.EnableFog;
			Program.Settings.fog_startDist.Value = AppSettings.Fog.FogDistance;
			Program.Settings.fog_density.Value = AppSettings.Fog.FogDensity;
			Program.Settings.fog_color.BackColor = AppSettings.Theming.Color_Fog;
			Program.Settings.gl_switch2wireframe.Checked = AppSettings.Rendering.WireframeInGame;
			Program.Settings.gl_showModels.Checked = AppSettings.Rendering.ModelsIn3dView;
			Program.Settings.comboBox6.SelectedItem = AppSettings.Rendering.LightingWhileMoving;
			Program.Settings.comboBox5.SelectedItem = AppSettings.Rendering.LightingWhileNotMoving;
			Program.Settings.cb_buffDepth.SelectedItem = AppSettings.Rendering.BufferDepth + " bits";
			Program.Settings.cb_filter.SelectedItem = AppSettings.Rendering.Filtering;

			Program.Settings.checkBox3.Checked = AppSettings.MapView.SelectedObjectRulers;
			Program.Settings.checkBox4.Checked = AppSettings.MapView.HighlightObectsOnHover;
			Program.Settings.checkBox5.Checked = AppSettings.MapView.BrushSubtractionOnlyWithCutter;

			Program.Settings.cb_presets.SelectedItem = AppSettings.Theming.Theme;
			Program.Settings.gridColor.BackColor = AppSettings.Theming.Color_Grid;
			Program.Settings.objColor.BackColor = AppSettings.Theming.Color_ObjectLines;
			Program.Settings.dupColor.BackColor = AppSettings.Theming.Color_Dups;
			Program.Settings.viewBGColor.BackColor = AppSettings.Theming.Color_2dViewBG;
			Program.Settings.brushEntColor.BackColor = AppSettings.Theming.Color_BrushEnts;
			Program.Settings.selObjColor.BackColor = AppSettings.Theming.Color_SelectedObjects;
			Program.Settings.viewBGColor3D.BackColor = AppSettings.Theming.Color_3dViewBG;
		}
		public static void SaveSettings()
		{
			AppSettings.General.AutoUpdate = Program.Settings.AutoUpdate.Checked;
			AppSettings.General.UndoRedoBuffer = (int)Program.Settings.numericUpDown2.Value;

			AppSettings.Fog.EnableFog = Program.Settings.cb_fog.Checked;
			AppSettings.Fog.FogDistance = (int)Program.Settings.fog_startDist.Value;
			AppSettings.Fog.FogDensity = (int)Program.Settings.fog_density.Value;
			AppSettings.Theming.Color_Fog = Program.Settings.fog_color.BackColor;
			AppSettings.Rendering.WireframeInGame = Program.Settings.gl_switch2wireframe.Checked;
			AppSettings.Rendering.ModelsIn3dView = Program.Settings.gl_showModels.Checked;
			AppSettings.Rendering.LightingWhileMoving = Program.Settings.comboBox6.SelectedItem.ToString();
			AppSettings.Rendering.LightingWhileNotMoving = Program.Settings.comboBox5.SelectedItem.ToString();
			AppSettings.Rendering.BufferDepth = int.Parse(Program.Settings.cb_buffDepth.SelectedItem.ToString().Remove(2));
			if (Program.Settings.cb_filter.SelectedIndex == 0)
				AppSettings.Rendering.Filtering = Globals.Filtering.Bilinear;
			else
				AppSettings.Rendering.Filtering = Globals.Filtering.Trilinear;
			AppSettings.MapView.SelectedObjectRulers = Program.Settings.checkBox3.Checked;
			AppSettings.MapView.HighlightObectsOnHover = Program.Settings.checkBox4.Checked;
			AppSettings.MapView.BrushSubtractionOnlyWithCutter = Program.Settings.checkBox5.Checked;

			AppSettings.Theming.Theme = Program.Settings.cb_presets.SelectedItem.ToString();
			AppSettings.Theming.Color_Grid = Program.Settings.gridColor.BackColor;
			AppSettings.Theming.Color_ObjectLines = Program.Settings.objColor.BackColor;
			AppSettings.Theming.Color_Dups = Program.Settings.dupColor.BackColor;
			AppSettings.Theming.Color_2dViewBG = Program.Settings.viewBGColor.BackColor;
			AppSettings.Theming.Color_BrushEnts = Program.Settings.brushEntColor.BackColor;
			AppSettings.Theming.Color_SelectedObjects = Program.Settings.selObjColor.BackColor;
			AppSettings.Theming.Color_3dViewBG = Program.Settings.viewBGColor3D.BackColor;

			foreach (CMapData map in mapDef.MapData)
			{
				int i = 0;
				foreach (Viewport vp in mapDef.MapData[i].Viewports)
				{
						vp.Scene.renderFog = AppSettings.Fog.EnableFog;
				}
				i++;
			}
			

			functions.InvalidateViewports();
		}

		public static void LoadMapSettings(Globals.Game Mode)
		{
			Program.ObjPane.DockState = AppSettings.MapView.DockedWindowPositions["ObjPane"];
			//Program.MatBrowser.DockState = AppSettings.MapView.DockedWindowPositions["MatBrowser"];
			Program.Prefabs.DockState = AppSettings.MapView.DockedWindowPositions["PrefabFactory"];
			//Program.CustObj.DockState = AppSettings.MapView.DockedWindowPositions["CustObj"];
		}

		public static void SetDefaults()
		{
            General.AutoUpdate = true;
            General.FirstRun = true;
            General.GameMode = Globals.Game.NONE;
            General.GridSize = 16;
            General.RecentFiles = new string[] { "" };
            General.UndoRedoBuffer = 256;

            Rendering.BufferDepth = 32;
            Rendering.DoubleBuffering = false;
            Rendering.EnableLighting = true;
            Rendering.EnableTransparency = true;
            Rendering.Filtering = Globals.Filtering.Bilinear;
            Rendering.LightingWhileMoving = "Simple";
            Rendering.LightingWhileNotMoving = "Full";
            Rendering.ModelsIn3dView = true;
            Rendering.Renderer = Globals.Renderers.TaoOpenGL;
            Rendering.WireframeInGame = true;

            Fog.EnableFog = true;
            Fog.FogDensity = 50;
            Fog.FogDistance = 1024;
            
            MouseKeyboardSettings.SetKeyDefaults();

            MapView.BrushSubtractionOnlyWithCutter = true;

            KeyValuePair<string, DockState> kvp = new KeyValuePair<string, DockState>();

            MapView.DockedWindowPositions.Add("ObjPane",DockState.DockRight);
            MapView.DockedWindowPositions.Add("MatBrowser", DockState.DockLeftAutoHide);
            MapView.DockedWindowPositions.Add("PrefabFactory", DockState.DockLeftAutoHide);
            MapView.DockedWindowPositions.Add("CustObj", DockState.DockRightAutoHide);

            LoadSettings();
		}

        public static void ReadMainSettingsINI()
        {
            ParilINI.IniFile file = new ParilINI.IniFile("MainSettings.ini");

            var section = file.GetSection("General");
            foreach (var item in section)
            {
                switch (item.Key)
                {
                    case "FirstRun":
                        AppSettings.General.FirstRun = functions.Convert2Bool(item.Value);
                        break;
                    case "UpdateCheck":
                        AppSettings.General.AutoUpdate = functions.Convert2Bool(item.Value);
                        break;
                    case "UndoRedoBuffer":
                        AppSettings.General.UndoRedoBuffer = int.Parse(item.Value);
                        break;
                    case "GridSize":
                        AppSettings.General.GridSize = int.Parse(item.Value);
                        break;
                    case "GameMode":
                        //go through supported games..
                        break;
                    case "Theme":
                        AppSettings.Theming.Theme = item.Value;
                        break;
                    case "RecentFiles":
                        AppSettings.General.RecentFiles = item.Value.Split(new char[] { ',' });
                        break;
                }
            }
            section = file.GetSection("Renderer");
            foreach (var item in section)
            {
                switch (item.Key)
                {
                    case "Renderer":
                        if (item.Value == "GL")
                            AppSettings.Rendering.Renderer = Globals.Renderers.TaoOpenGL;
                        else if (item.Value == "DX")
                            AppSettings.Rendering.Renderer = Globals.Renderers.SlimDX;
                        break;
                    case "EnableLighting":
                        AppSettings.Rendering.EnableLighting = functions.Convert2Bool(item.Value);
                        break;
                    case "EnableTransparency":
                        AppSettings.Rendering.EnableTransparency = functions.Convert2Bool(item.Value);
                        break;
                    case "LightingWhileMoving":
                        AppSettings.Rendering.LightingWhileMoving = item.Value;
                        break;
                    case "LightingWhileNotMoving":
                        AppSettings.Rendering.LightingWhileNotMoving = item.Value;
                        break;
                    case "DoubleBuffering":
                        AppSettings.Rendering.DoubleBuffering = functions.Convert2Bool(item.Value);
                        break;
                    case "BufferDepth":
                        AppSettings.Rendering.BufferDepth = int.Parse(item.Value);
                        break;
                    case "Filtering":
                        if (item.Value == "Bilinear")
                            AppSettings.Rendering.Filtering = Globals.Filtering.Bilinear;
                        else if (item.Value == "Trilinear")
                            AppSettings.Rendering.Filtering = Globals.Filtering.Trilinear;
                        break;
                    case "WireframeInGame":
                        AppSettings.Rendering.WireframeInGame = functions.Convert2Bool(item.Value);
                        break;
                    case "ModelsIn3dView":
                        AppSettings.Rendering.ModelsIn3dView = functions.Convert2Bool(item.Value);
                        break;
                }
            }
            section = file.GetSection("Fog");
            foreach (var item in section)
            {
                switch (item.Key)
                {
                    case "EnableFog":
                        AppSettings.Fog.EnableFog = functions.Convert2Bool(item.Value);
                        break;
                    case "FogDensity":
                        AppSettings.Fog.FogDensity = int.Parse(item.Value);
                        break;
                    case "FogDistance":
                        AppSettings.Fog.FogDistance = int.Parse(item.Value);
                        break;
                }
            }
            section = file.GetSection("Keyboard Settings");
            //not going to tackle section this right now (9/14/2010)
            section = file.GetSection("Map View");
            foreach (var item in section)
            {
                switch (item.Key)
                {
                    case "SelectedObjectRulers":
                        AppSettings.MapView.SelectedObjectRulers = functions.Convert2Bool(item.Value);
                        break;
                    case "HighlightObjectsOnHover":
                        AppSettings.MapView.HighlightObectsOnHover = functions.Convert2Bool(item.Value);
                        break;
                    case "BrushSubtractionOnlyWithCutter":
                        AppSettings.MapView.BrushSubtractionOnlyWithCutter = functions.Convert2Bool(item.Value);
                        break;
                    case "DockedWindowPositions":
                        string[] s = item.Value.Split(new char[] { '|' });
                        AppSettings.MapView.DockedWindowPositions.Clear();
                        foreach (var it in s)
                        {
                            string[] delim = it.Split(new char[] { ',' });
                            DockState ds = new DockState();

                            switch (delim[1])
                            {
                                case "DockLeft":
                                    ds = DockState.DockLeft;
                                    break;
                                case "DockRight":
                                    ds = DockState.DockRight;
                                    break;
                                case "DockLeftAutoHide":
                                    ds = DockState.DockLeftAutoHide;
                                    break;
                                case "DockRightAutoHide":
                                    ds = DockState.DockRightAutoHide;
                                    break;
                            }
                            AppSettings.MapView.DockedWindowPositions[delim[0]] = ds;
                        }
                        break;
                }
            }
            section = file.GetSection("Model View");
            section = file.GetSection("Texture View");

            Dictionary<string, Color> d;

            if (System.IO.File.Exists("themes.ini"))
            {
                file = new ParilINI.IniFile("themes.ini");

                Program.Settings.cb_presets.Items.Clear();
                foreach (KeyValuePair<string, Dictionary<string, string>> entry in file.Entries)
                {
                    d = new Dictionary<string, Color>();
                    Program.Settings.cb_presets.Items.Add(entry.Key);
                    foreach (KeyValuePair<string, string> kvp in entry.Value)
                    {
                        string[] RGB = kvp.Value.Split(new char[] { ',' });

                        Color c = new Color();
                        c = Color.FromArgb(int.Parse(RGB[0]), int.Parse(RGB[1]), int.Parse(RGB[2]));

                        d[kvp.Key] = c;
                    }
                    Program.Settings.presets.Add(d);
                }
                Program.Settings.cb_presets.SelectedItem = "Default";

                section = file.GetSection(AppSettings.Theming.Theme);
                d = new Dictionary<string, Color>();
                foreach (var item in section)
                {
                    string[] RGB = item.Value.Split(new char[] { ',' });

                    Color c = new Color();
                    c = Color.FromArgb(int.Parse(RGB[0]), int.Parse(RGB[1]), int.Parse(RGB[2]));
                    switch (item.Key)
                    {
                        case "Color_Grid":
                            AppSettings.Theming.Color_Grid = c;
                            break;
                        case "Color_2dViewBG":
                            AppSettings.Theming.Color_2dViewBG = c;
                            break;
                        case "Color_3dViewBG":
                            AppSettings.Theming.Color_3dViewBG = c;
                            break;
                        case "Color_BrushEnts":
                            AppSettings.Theming.Color_BrushEnts = c;
                            break;
                        case "Color_Dups":
                            AppSettings.Theming.Color_Dups = c;
                            break;
                        case "Color_ObjectLines":
                            AppSettings.Theming.Color_ObjectLines = c;
                            break;
                        case "Color_VertexHandles":
                            AppSettings.Theming.Color_VertexHandles = c;
                            break;
                        case "Color_SelectedObjects":
                            AppSettings.Theming.Color_SelectedObjects = c;
                            break;
                        case "Color_Fog":
                            AppSettings.Theming.Color_Fog = c;
                            break;
                    }
                }
            }


        }
		public static void ReadGameSettingsINI(string path)
		{
			ParilINI.IniFile file = new ParilINI.IniFile(path);

			var section = file.GetSection("General");
			if (section.ContainsKey("game_path"))
			{
				AppSettings.Gamemode.GameExecutable = section["game_exec"];
				AppSettings.Gamemode.GameTexDir = section["game_texPath"];
			}
			section = file.GetSection("Build Apps");

			int i = 0;
			AppSettings.Gamemode.BuildTools.Clear();
			foreach (var item in section)
			{
				if (section.ContainsKey(item.Key))
				{
					Program.Settings.Tba[i].Text = item.Value;
					AppSettings.Gamemode.BuildTools.Add(item.Value);
				}

				i++;
			}
			i = 0;
			section = file.GetSection("Custom Build Menu");
			AppSettings.Gamemode.CustomBuildMenu.Clear();
			foreach (var item in section)
			{
				List<string> li = new List<string>();
				string[] sa = item.Value.Split(new char[] { '|' });
				foreach (string val in sa)
					li.Add(val);
				AppSettings.Gamemode.CustomBuildMenu.Add(item.Key, li);
				i++;
			}
		}

		public static void WriteMainINI()
		{	}
		public static void WriteGameINI()
		{	}
		public static void WriteThemesINI()
		{
			using (StreamWriter sr = new StreamWriter("themes.ini"))
			{
				int i = 0;
				foreach (Dictionary<string, Color> d in Program.Settings.presets)
				{
					sr.WriteLine("[" + Program.Settings.cb_presets.Items[i] + "]");
					foreach (KeyValuePair<string, Color> kvp in d)
					{
						sr.WriteLine(kvp.Key + "=" + kvp.Value.R + "," + kvp.Value.G + "," + kvp.Value.B);
					}
					sr.WriteLine();
					i++;
				}
			}
		}
	}
}
